#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdlib.h>
#include <signal.h>
#include <poll.h>


int key_fd, led_fd, beep_fd;

void handler(int signum)
{
	close(key_fd);	
	close(led_fd);
	close(beep_fd);
	exit(0);
	return ;
}

void key_handler(int signum)
{
	int val;
	char sta;
	/* 读取按键值 */
	read(key_fd, &val, 4);

	printf("key is %d, value = %d\n", (val >> 8), (val & 0xff));
	
	/* 1：蜂鸣器响 */
	if((val & 0xff) == 0){
		sta = 1;
		write(beep_fd, &sta, 1);
	}
	/* 0：蜂鸣器灭 */
	else{
		sta = 0;
		write(beep_fd, &sta, 1);
	}
	
}

int main(int argc, char *argv[])
{
	char buf[10];
	
	int val;
	char status = 1;
	int flags;
	int tim;

	signal(SIGINT, handler);  /* ctrl+c */
	signal(SIGIO, key_handler);
	
	if(argc < 2 || argc > 3){
		printf("please input 2 or 3 args, like\n");
		printf("./dev_test <dev> [string]\n");
		return 0;
	}

	key_fd = open(argv[1], O_RDWR);
	if(key_fd < 0){
		printf("file open failed\n");
		return 1;
	}

	/* F_SETOWN: 设置将接收SIGIO和SIGURG信号的进程id */
	fcntl(key_fd, F_SETOWN, getpid());
	
	/*  F_GETFL: 取得fd的文件状态标志 */
	flags = fcntl(key_fd, F_GETFL);
	
	/* O_ASYNC: 当I/O可用的时候,允许SIGIO信号发送到进程组,
	   例如:当有数据可以读的时候 */
	fcntl(key_fd, F_SETFL, flags | O_ASYNC);  //启动驱动的fasync功能
	

	/* 打开led设备 */
	led_fd = open("/dev/led", O_RDWR);
	if(led_fd < 0){
		printf("/dev/led open failed\n");
		return 1;
	}

	/* 打开beep设备 */
	beep_fd = open("/dev/beep", O_RDWR);
	if(beep_fd < 0){
		printf("/dev/beep open failed\n");
		return 1;
	}

	while(1){
		/* led闪烁功能 */
		write(led_fd, &status, 1);
//		sleep(1);
		for(tim = 0; tim < 500; tim++)
			usleep(1000);
		status ^= 1;
	}

	
	return 0;
}

